Skip to content

Stabilize inlay hints during incomplete edits - #787

Merged
renkun-ken merged 6 commits into
REditorSupport:masterfrom
renkun-ken:codex/stabilize-inlay-hints
Oct 10, 2026
Merged

renkun-ken merged 6 commits into
REditorSupport:masterfrom
renkun-ken:codex/stabilize-inlay-hints

Conversation

@renkun-ken

@renkun-ken renkun-ken commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Temporary syntax errors while typing currently clear parameter-name inlay hints across the document, making unrelated lines shift as hints disappear and reappear. Preserve the last valid call index for untouched calls, move their UTF-16 positions with incremental edits, and refresh it after successful parsing.

Discard calls intersecting an edit and conservatively invalidate following calls when comments or strings may change lexical context. Invalidate calls when inserts, replacements, or deletions ending at or separated from the callee by spaces or tabs can change its name, namespace, or member context. Retain previously resolved parameter names during parse failures, honor current hint settings and viewport ranges, and restrict Quarto/R Markdown fallback hints to omitted R cells so fresh results take precedence.

Hints for the call being edited may still disappear until it parses successfully. Visual verification of flickering in VS Code remains outstanding.

Related: REditorSupport/vscode-R#1853

Validation:

  • Installed this branch into a temporary R library and passed the seven focused suites: inlay-hint, range-index, document-core, handlers-textsync, handlers-langfeatures, codeunits, and literate.
  • Added a language-server process regression confirming that inserting an incomplete call preserves existing hints.
  • Covered sequential Unicode edits, nested calls, local parameter names, full replacements, comments/strings, viewport ranges, settings, and incomplete literate cells.
  • Added regressions for prefix replacements ending at a call, including $, @, ::, renamed callees, multiline replacements, and deletion joining a call to a member prefix. These fail before the boundary fix and pass afterward; whitespace replacements still preserve hints. Added whitespace-separated prefix regressions for spaces, tabs, member and namespace prefixes, and UTF-16 positions, plus a check that intervening tokens preserve unrelated calls.
  • Typing benchmark on R 4.6.1: five runs of 200 incremental edits on a 10,001-line document containing 10,000 stats::rnorm(10, 1, 2) calls, alternating insertion/deletion on the blank middle line. Median time was 2.530 ms per edit with the cached call-index update versus 0.080 ms without it, adding 2.450 ms per edit. The benchmark includes document content updates and keeps all 10,000 calls cached throughout; it excludes background parsing and editor rendering.
  • Allowed 60 seconds under coverage for the source-closure signature regression, which waits for two background parses; normal tests retain the 10-second limit. The full coverage shard 2 passes locally with 1,084 assertions and no failures.
  • git diff --check passed; no new lint findings in changed code.

@renkun-ken
renkun-ken requested a review from eitsupi October 8, 2026 23:33

@eitsupi eitsupi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This review was conducted with ChatGPT.

The overall approach looks sound and should significantly improve the issue reported in REditorSupport/vscode-R#1853 without disabling inlay hints.

I noticed one edge case in inlay_hint_apply_change() that may need fixing before merging:

  • When an edit ends exactly at the start of a call, the call is considered untouched. For example, replacing x <- with obj$ in x <- target(a, b) produces obj$target(a, b). The cached hints may be preserved during a subsequent parse error, even though member calls are intentionally excluded from inlay hints.
  • The current boundary check only handles insertions at the call's start, not replacements ending there. Could you address this case and add a regression test?

Two non-blocking suggestions:

  • Since incremental edits now update and reorder the cached call index, a quick typing-performance benchmark on a large file would be useful.
  • Manual verification in VS Code would help confirm that the flickering reported in #1853 is sufficiently reduced.

Otherwise, the implementation and test coverage look promising.

@eitsupi eitsupi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This review was conducted with ChatGPT.

The previous concern has been addressed. One additional non-blocking test suggestion:

Replacing x <- with obj$ in x <- target(a, b) leaves a space before target, producing obj$ target(a, b). Since the edit ends before the callee rather than exactly at its start, the cached hints may incorrectly survive a subsequent parse error.

A regression test covering this whitespace-separated boundary would be useful.

@renkun-ken
renkun-ken merged commit f188ad9 into REditorSupport:master Oct 10, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants